// Drawing functions with clipping support
//
// NOTE: Drawing outside the canvas is safe and the excess will be clipped!
//

#ifndef __DRAW_H__
#define __DRAW_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "Canvas.h"
#include "Image.h"

// Filling types for polygon
#define FILLTYPE_NORMAL			0
#define FILLTYPE_DOT			1
#define FILLTYPE_INTERLEAVE		2

// Params:
//  canvas      is the pointer of output/or refered canvas
//  x1,y1,x2,y2 is the starting/ending x,y coords of line (x1,y1)-(x2,y2)
//  l,t,r,b     is the left-top/right-bottom x,y coords of rectangle (l,t)-(r,b)
//  color       is the rgb value, plz use _RGB(r,g,b) macro to make it

/////////////////////////////////////////////////////////////////////////////
// Clipping functions

// return 1 inside the canvas/or been clipped in params!
//        0 outside the canvas!
int  g_LineClipping(const TCanvas *canvas, int *x1, int *y1, int *x2, int *y2);
int  g_LineClipping1(TRect rect, int *x1, int *y1, int *x2, int *y2);

int  g_RectClipping(const TCanvas *canvas, int *l, int *t, int *r, int *b);


/////////////////////////////////////////////////////////////////////////////
// Canvas drawing functions

void g_DrawPixel(const TCanvas *canvas, int x, int y, int color);

/* arbitrary line */
void g_DrawLine(const TCanvas *canvas, int x1, int y1, int x2, int y2, int color);

/* horizontal line (x1,y1)-(x2,y1) */
void g_DrawHLine(const TCanvas *canvas, int x1, int y1, int x2, int color);

/* vertical line  (x1,y1)-(x1,y2) */
void g_DrawVLine(const TCanvas *canvas, int x1, int y1, int y2, int color);

void g_DrawRect(const TCanvas *canvas, int l, int t, int r, int b, int color);

void g_DrawCircle(const TCanvas *canvas, int x, int y, int radius, int color);

void g_DrawImage(const TCanvas *canvas, int x, int y, const TImage *image);

void g_SaveImage(const TCanvas *canvas, int l, int t, int r, int b, TImage *image);

/* Draw image with key(transparent) color passed */
void g_DrawImageTrans(const TCanvas *canvas, int x, int y, const TImage *image, int keyColor);

/* Draw the RLE(OB's Transparent Run Length Encoded) images */
//void g_DrawRle(const TCanvas *canvas, int x, int y, const TImage *rle);

void g_FillRectRadiate(const TCanvas *canvas, int l, int t, int r, int b, int btm_color, int top_color);

void g_FillRect(const TCanvas *canvas, int l, int t, int r, int b, int color);

void g_FillCircle(const TCanvas *canvas, int x, int y, int radius, int color);
void g_FillCircleBlend(const TCanvas *canvas, int x, int y, int radius, int color, int src, int des);

/* NOTE: it will auto closed if ending point is not the same as starting point. */
void g_DrawPolyline(const TCanvas *canvas, const TPoint *points, int count, int color);

/* NOTE: 1. it will auto closed if ending point is not the same as starting point
         2. polygon can be convex or concave but can't be complex!
               _      _   _          _  _
             _| |_   | |_| |        | \/ |
            |_____|  |_____| is ok, |_/\_| is not ok
*/
void g_FillPolygon(const TCanvas *canvas, TPoint *points, int count, int color, int fillType);


/////////////////////////////////////////////////////////////////////////////
// Alpha blending functions

// Darken is RGBnew = RGBsrc / 2 + RGBdst / 2, i.e. blend(50, 50)
void g_DrawImageDarken(const TCanvas *canvas, int x, int y, const TImage *image);

void g_FillRectDarken(const TCanvas *canvas, int l, int t, int r, int b, int color);

// Blend is RGBnew = RGBsrc * sf/100 + RGBdst * df/100
//	sf		is source factor 0 ~ 100
//	df		is destination factor 0 ~ 100
void g_DrawImageBlend(const TCanvas *canvas, int x, int y, const TImage *image, int sf, int df);

void g_FillRectBlend(const TCanvas *canvas, int l, int t, int r, int b, int color, int sf, int df);

// Alpha is RGBnew = RGBsrc * a/255 + RGBdst * (255-a)/255, a is 0 ~ 255
//	alpha	is alpha values for mapping each pixels in image
void g_DrawImageAlpha(const TCanvas *canvas, int x, int y, const TImage *image, const UInt8 *alpha);

void g_DrawPixelAlpha(const TCanvas* canvas, int x, int y, int color, UInt8 alpha);

void g_DrawHLineDarken(const TCanvas *canvas, int x1, int y1, int x2, int color);

void g_DrawVLineDarken(const TCanvas *canvas, int x1, int y1, int x2, int color);

#ifdef __cplusplus
}
#endif

#endif  // __DRAW_H__
